﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SingleBlog.Core.Services
{
    using Data;
    using Microsoft.Extensions.Caching.Memory;
    using SingleBlog.Core.Resources;
    using System.Threading.Tasks;
    using Microsoft.EntityFrameworkCore;
    using System.Linq;

    /// <summary>
    /// 文章的回复服务。
    /// </summary>
    public class CommentService
    {
        const string CACHE_COMMENTS = "SingleBlog-Comments-a:{0}";

        private readonly SingleBlogDbContext _context;
        private readonly IMemoryCache _cache;
        public CommentService(SingleBlogDbContext context,IMemoryCache cache)
        {
            _context = context;
            _cache = cache;
        }

        public Task<IEnumerable<Comment>> GetCommentsAsync(int articleId)
            => _cache.GetOrCreateAsync(CACHE_COMMENTS.StringFormat(articleId), (entry)
                  => Task.Run(() => _context.Comments.Where(m => m.ArticleId == articleId).ToList().AsEnumerable()));

        /// <summary>
        /// 以异步的方式保存回复。
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">item</exception>
        public Task SaveCommentAsync(Comment item)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            if (item.Id == 0)
            {
                _context.Comments.Add(item);
            }
            else
            {
                _context.Entry(item).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
            }
            return _context.SaveChangesAsync(); 
        }

        /// <summary>
        /// 以异步的方式删除指定的回复。
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns></returns>
        /// <exception cref="NullReferenceException"></exception>
        public async Task DeleteCommentsAsync(int id)
        {
            var entityToDelete = await _context.Comments.FindAsync(id);
            if (entityToDelete == null)
            {
                throw new NullReferenceException(Language.CommentNotFound.StringFormat(id));
            }

            _context.Comments.Remove(entityToDelete);
            await _context.SaveChangesAsync();
        }
    }
}
